﻿#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Excel;
using System.Data;
using OfficeOpenXml;

public class TransformCNtoVN : MonoBehaviour
{
	static List<DictionaryDate> mDictionary = new List<DictionaryDate>();
	static List<ExeclDate> AllExeclDate = new List<ExeclDate>();
	static Dictionary<string, ExeclDate> NotTraned = new Dictionary<string, ExeclDate> ();
	static int DicCount = 0;

	[MenuItem ("AiFeng/Transform CN To VN")]
	static void TransCNtoVN ()
	{
#if !VN
		Debug.Log("需先加宏定义 VN ");
		return;
#endif
		ReadXLSX ();
		RePlaceScriptsText ();
		RePlaceSceneLabelText ();
		RePlaceAssetsLabelText ();
		WriteXLSX ();
		AssetDatabase.Refresh ();
	}

	//读取xlsx
	static void ReadXLSX ()
	{
		mDictionary.Clear ();
		AllExeclDate.Clear ();
		NotTraned.Clear ();
		DicCount = 1;
		string ExeclPaths = Application.dataPath.Replace ("Assets", "AssetsVN") + "/已翻译好的Execl/";
		try
		{
			string[] AllExecls = Directory.GetFiles(ExeclPaths, "*.xlsx", SearchOption.AllDirectories);
			foreach (string path in AllExecls)
			{
				ExcelRead (path);
			}
//			Debug.Log (mDictionary.Count);
		}
		catch (System.Exception error)
		{
			Debug.Log(error.Message);
		}
	}

	static void ExcelRead (string path)
	{
		FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read);
		if (stream != null)
		{
			IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
			if (excelReader != null)
			{
				do
				{
//					Debug.Log("Sheet Name: " + excelReader.Name);
					while (excelReader.Read())
					{
						DictionaryDate date = new DictionaryDate();
						for (int i = 0; i < excelReader.FieldCount; i ++)
						{
							string content = excelReader.IsDBNull(i) ? "" : excelReader.GetString(i);
							if (string.IsNullOrEmpty(content))
							{
								continue;
							}
							if (i == excelReader.FieldCount - 2)
							{
								date.Key_CN = content;
							}
							else if (i == excelReader.FieldCount - 1)
							{
								date.Key_VN = content;
							}
						}
						if (!string.IsNullOrEmpty(date.Key_CN) && !string.IsNullOrEmpty(date.Key_VN))
						{
							date.Index = DicCount;
							Debug.Log(DicCount + " CN: " + date.Key_CN + " VN: " + date.Key_VN);
							mDictionary.Add(date);
							DicCount ++;
						}
						if (path.Contains("客户端需要重新翻译的中文夹越南文"))
						{
							DictionaryDate newdate = new DictionaryDate();
							for (int i = 0; i < excelReader.FieldCount; i ++)
							{
								string content = excelReader.IsDBNull(i) ? "" : excelReader.GetString(i);
								if (string.IsNullOrEmpty(content))
								{
									continue;
								}
								if (i == 0)
								{
									newdate.Key_CN = content;
								}
								else if (i == excelReader.FieldCount - 1)
								{
									newdate.Key_VN = content;
								}
							}
							if (!string.IsNullOrEmpty(newdate.Key_CN) && !string.IsNullOrEmpty(newdate.Key_VN))
							{
								newdate.Index = DicCount;
								Debug.Log(DicCount + " CN: " + newdate.Key_CN + " VN: " + newdate.Key_VN);
								mDictionary.Add(newdate);
								DicCount ++;
							}
						}
					}
				}
				while (excelReader.NextResult());
			}
		}
	}

	static void RePlaceSceneLabelText ()
	{
		GameObject[] AllSceneObjects = (GameObject[])Resources.FindObjectsOfTypeAll(typeof(GameObject));
		List<GameObject> AllObjects = new List<GameObject>();
		foreach (GameObject Obj in AllSceneObjects)
		{
			if (Obj == null)
			{
				continue;
			}
			if (Obj.hideFlags == HideFlags.NotEditable)
			{
				continue;
			}
			if (Obj.hideFlags == HideFlags.HideAndDontSave)
			{
				continue;
			}
			AllObjects.Add(Obj);
		}
		foreach (GameObject value in AllObjects)
		{
			UILabel[] labels = value.GetComponentsInChildren<UILabel>(true);
			if (labels.Length == 0)
			{
				continue;
			}
			foreach (UILabel eachLabel in labels)
			{
				if (string.IsNullOrEmpty(eachLabel.text))
				{
					continue;
				}
				char[] allChar = eachLabel.text.ToCharArray();
				foreach (char ch in allChar)
				{
					if (ch >= 0x4e00 && ch <= 0x9fa5) 
					{
						eachLabel.text = FindInDictionary(eachLabel.text, value.name, eachLabel.name);
						break;
					}
				}
			}
		}
	}

	static void RePlaceAssetsLabelText ()
	{
		string[] allpaths = AssetDatabase.GetAllAssetPaths ();
		foreach (string path in allpaths)
		{
			if (!path.Contains("Assets/Resources/") && !path.Contains("Assets/ResourcesAsset/"))
			{
				continue;
			}
			if (path.Contains("AssetsVN/") || path.Contains("Assets/ResourcesVN/") || path.Contains("Assets/ResourcesAssetVN/"))
			{
				continue;
			}
			Object obj = AssetDatabase.LoadMainAssetAtPath(path);
			if (obj == null)
			{
				continue;
			}
			GameObject go = obj as GameObject;
			if (go == null)
			{
				continue;
			}
			UILabel[] labels = go.GetComponentsInChildren<UILabel>(true);
			if (labels.Length == 0)
			{
				continue;
			}
			foreach (UILabel eachLabel in labels)
			{
				if (string.IsNullOrEmpty(eachLabel.text))
				{
					continue;
				}
				char[] allChar = eachLabel.text.ToCharArray();
				foreach (char ch in allChar)
				{
					if (ch >= 0x4e00 && ch <= 0x9fa5) 
					{
						eachLabel.text = FindInDictionary(eachLabel.text, path, eachLabel.name);
						break;
					}
				}
			}
		}
	}

	static void RePlaceScriptsText ()
	{
		string[] filePaths1 = null;
		string[] filePaths2 = null;
		string[] filePaths3 = null;
		string[] filePaths4 = null;
		try
		{
			filePaths1 = Directory.GetFiles(Application.dataPath, "*.cs", SearchOption.AllDirectories);
			filePaths2 = Directory.GetFiles(Application.dataPath, "*.json", SearchOption.AllDirectories);
			filePaths3 = Directory.GetFiles(Application.dataPath, "*.txt", SearchOption.AllDirectories);
			filePaths4 = Directory.GetFiles(Application.dataPath, "*.xml", SearchOption.AllDirectories);
		}
		catch (System.Exception error)
		{
			Debug.Log(error.Message);
		}
		List<string> filePaths = new List<string> ();
		foreach (string path in filePaths1)
		{
			filePaths.Add(path);
		}
		foreach (string path in filePaths2)
		{
			filePaths.Add(path);
		}
		foreach (string path in filePaths3)
		{
			filePaths.Add(path);
		}
		foreach (string path in filePaths4)
		{
			filePaths.Add(path);
		}
		foreach (string path in filePaths)
		{
			if (!path.Contains("Resources") && !path.Contains("ResourcesAsset") && !path.Contains("Script") && !path.Contains("StreamingAssets"))
			{
				continue;
			}
			if (path.Contains("NGUI") || path.Contains("TK2DROOT") || path.Contains("texiao_scene"))
			{
				continue;
			}
			int lastIndex = path.LastIndexOf("/");
			string FilePath = path.Remove(0, lastIndex + 1);
			Debug.Log(FilePath);
			string[] allLines = File.ReadAllLines(FilePath);
			string OutText = "";
			for (int i = 0; i < allLines.Length; i ++)
			{
				string ThisLine = allLines [i];
				if (ThisLine.Contains ("///") || ThisLine.Contains ("region") || ThisLine.Contains ("endregion") || 
				    ThisLine.Contains ("Debug.Log") || ThisLine.Contains ("/*") || ThisLine.Contains ("*/"))
				{
					OutText += ThisLine + "\r\n";
					continue;
				}
				bool haschinese = false;
				char[] allChar = ThisLine.ToCharArray();
				foreach (char ch in allChar)
				{
					if (ch >= 0x4e00 && ch <= 0x9fa5) 
					{
						haschinese = true;
						break;
					}
				}
				if (!haschinese)
				{
					OutText += ThisLine + "\r\n";
					continue;
				}
				if (ThisLine.Contains ("//"))
				{
					int index = ThisLine.IndexOf ("//");
					if (index == 0)
					{
						OutText += ThisLine + "\r\n";
						continue;
					}
					string Left = ThisLine.Substring (0, index);
					string Right = ThisLine.Replace (Left, "");
					if (!string.IsNullOrEmpty(Left))
					{
						char[] mChar = Left.ToCharArray();
						foreach (char ch in mChar)
						{
							if (ch >= 0x4e00 && ch <= 0x9fa5) 
							{
								Left = PatchScript (Left, path, i + 1);
								break;
							}
						}
					}
					ThisLine = Left + Right;
				}
				else
				{
					ThisLine = PatchScript (ThisLine, path, i + 1);
				}
				OutText += ThisLine + "\r\n";
			}
			try
			{
				string OldText = File.ReadAllText(FilePath);
				if (OutText != OldText)
				{
					bool hasbom = true;
					if (path.Contains(".xml"))
					{
						hasbom = false;
					}
					System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding(hasbom);
					File.WriteAllText(path, OutText, utf8);
				}
			}
			catch (System.Exception error)
			{
				Debug.Log(error.Message);
				continue;
			}
		}
	}

	static string PatchScript (string input, string path, int line)
	{
		string output = input;
		foreach (DictionaryDate date in mDictionary)
		{
			output = output.Replace(date.Key_CN, date.Key_VN);
		}
		if (output == input)
		{
			if (!NotTraned.ContainsKey(input))
			{
				ExeclDate date = new ExeclDate();
				date.cell1 = path;
				date.cell2 = "第" + line.ToString() + "行";
				date.cell3 = input;
				AllExeclDate.Add(date);
				NotTraned.Add(input, date);
			}
		}
		return output;
	}

	static string FindInDictionary (string input, string path, string name)
	{
		string output = input;
		foreach (DictionaryDate date in mDictionary)
		{
			output = output.Replace(date.Key_CN, date.Key_VN);
		}
		if (output == input)
		{
			if (!NotTraned.ContainsKey(input))
			{
				ExeclDate date = new ExeclDate();
				date.cell1 = path;
				date.cell2 = name;
				date.cell3 = input;
				AllExeclDate.Add(date);
				NotTraned.Add(input, date);
			}
		}
		return output;
	}

	static void WriteXLSX ()
	{
		string path = Application.dataPath.Replace("Assets", "AssetsVN") + "/未翻译的文本.xlsx";
		Debug.Log (path);
		try
		{
			FileStream fs = new FileStream(path, FileMode.Create);
			using (ExcelPackage package = new ExcelPackage(fs))
			{
				ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("客户端");
				for (int i = 0; i < AllExeclDate.Count; i ++)
				{
					worksheet.Cells[i + 1, 1].Value = AllExeclDate[i].cell1;
					worksheet.Cells[i + 1, 2].Value = AllExeclDate[i].cell2;
					worksheet.Cells[i + 1, 3].Value = AllExeclDate[i].cell3;
				}
				package.Save();
			}
			fs.Close();
		}
		catch (System.Exception error)
		{
			Debug.Log(error.Message);
		}
	}
}

public class DictionaryDate 
{
	public int Index = 0;
	public string Key_CN = "";
	public string Key_VN = "";
}
#endif